package gov.nasa.anml.lifted;

import java.util.*;

import gov.nasa.anml.PDDL;
import gov.nasa.anml.State;
import gov.nasa.anml.PDDL.FloatExpression;
import gov.nasa.anml.PDDL.Time;
import gov.nasa.anml.utility.SimpleObject;
import gov.nasa.anml.utility.SimpleString;
import gov.nasa.anml.utility.SimpleVoid;

public class VectorType extends Term<SimpleString,SimpleVoid> implements Type<ArrayList<SimpleObject<?>>> {
	//extends Type<SimpleObject> implements Scope {

	public Constraint<ArrayList<SimpleObject<?>>> constraint=null;

	//public StructuredType parent;
	
	public VectorType() {
		super();
	}
	public VectorType(SimpleString n) {
		super(n);
	}
	public VectorType(SimpleString n,int i) {
		super(n,i);
	}
	public VectorType(Constraint<ArrayList<SimpleObject<?>>> c) {
		super();
		constraint = c;
	}
	
	public final TypeCode typeCode() {
		return TypeCode.Vector;
	}

	public IdentifierCode idCode() {
		return IdentifierCode.Type;
	}
	
	public VectorType constrain(Constraint<ArrayList<SimpleObject<?>>> c) {
		if (constraint == null || constraint.containsAll(c))
			return new VectorType(c);
		return null;
	}
	
	public VectorType clone() {
		VectorType ret = null;
		ret = (VectorType) super.clone();
		return ret;
	}
	
	public History<SimpleVoid> storage(State p, State c) {
		return null;
	}
	public SimpleString value(State s) {
		System.err.println("This is not really implemented (VectorType).");
		return name; // a pretty arbitrary choice, but helps avoid NPE.
	}
	
	// see PrimitiveType
	// a vector of symbols could sortof be handled, but translating out component-wise assignments
	// in the cartesian product space would be really annoying.  The right way is to use functions (to symbols),
	// which don't exist in PDDL [as they amount to vector types at best, and much worse if unrestricted].
	public PDDL.Type asPDDLType() {
		return null;
	}
	public void translateDecl(PDDL pddl,Interval unit) {
	}
	
	
	/*
	// Scope implementation


	public SymbolTable<Type<?>> types = new SymbolTable<Type<?>>();
	public SymbolTable<Constant<?>> cFluents = new SymbolTable<Constant<?>>();
	public SymbolTable<ConstantFunction<?>> cFluentFunctions = new SymbolTable<ConstantFunction<?>>();
	public SymbolTable<Fluent<?>> fluents = new SymbolTable<Fluent<?>>();
	public SymbolTable<FluentFunction<?>> fluentFunctions = new SymbolTable<FluentFunction<?>>();
	public SymbolTable<Parameter<?>> parameters ;//= new SymbolTable<Parameter<?>>();
	public SymbolTable<Action> actions ;//= new SymbolTable<Action>(); 
	
	public ArrayList<Statement> statements = new ArrayList<Statement>(); 

	// one namespace by simple id.  Should eventually implement
	// type-signature mapping.
	public HashMap<SimpleString,Identifier> symbols = new HashMap<SimpleString,Identifier>();

	
	public Identifier addSymbol(IdentifierImp s) {
		return symbols.put(s.name,s);
	}
	
	public Identifier getSymbol(SimpleString s) {
		return symbols.get(s);
	}


	public <T extends SimpleObject<? super T>> Parameter<T> addParameter(Parameter<T> t) {
		symbols.put(t.name,t);
		return (Parameter<T>) parameters.put(t);
	}
	
	public <T extends SimpleObject<? super T>> Type<T> addType(Type<T> t) {
		symbols.put(t.name(),t);
		return (Type<T>) types.put(t);
	}

	public <T extends SimpleObject<? super T>> Constant<T> addConstant(Constant<T> c) {
		symbols.put(c.name,c);
		return (Constant<T>) cFluents.put(c);
	}

	public <T extends SimpleObject<? super T>> ConstantFunction<T> addConstantFunction(ConstantFunction<T> c) {
		symbols.put(c.name,c);
		return (ConstantFunction<T>) cFluentFunctions.put(c);
	}

	public <T extends SimpleObject<? super T>> Fluent<T> addFluent(Fluent<T> f) {
		symbols.put(f.name,f);
		return (Fluent<T>) fluents.put(f);
	}

	public <T extends SimpleObject<? super T>> FluentFunction<T> addFluentFunction(FluentFunction<T> f) {
		symbols.put(f.name,f);
		return (FluentFunction<T>) fluentFunctions.put(f);
	}

	public Action addAction(Action a) {
		symbols.put(a.name,a);
		return actions.put(a);
	}

	public SimpleString getParameterName(int p) {
		return parameters.getName(p);
	}
	
	public SimpleString getTypeName(int t) {
		return types.getName(t);
	}

	public SimpleString getConstantFluentName(int c) {
		return cFluents.getName(c);
	}
	
	public SimpleString getConstantFunctionName(int c) {
		return cFluentFunctions.getName(c);
	}

	public SimpleString getFluentName(int f) {
		return fluents.getName(f);
	}

	public SimpleString getFunctionName(int f) {
		return fluentFunctions.getName(f);
	}

	public SimpleString getActionName(int a) {
		return actions.getName(a);
	}

	public Parameter<?> getParameter(int p) {
		return parameters.get(p);
	}
	
	public Type<?> getType(int t) {
		return types.get(t);
	}

	public Constant<?> getConstant(int c) {
		return cFluents.get(c);
	}

	public ConstantFunction<?> getConstantFunction(int c) {
		return cFluentFunctions.get(c);
	}

	public Fluent<?> getFluent(int f) {
		return fluents.get(f);
	}

	public FluentFunction<?> getFluentFunction(int f) {
		return fluentFunctions.get(f);
	}

	public Action getAction(int a) {
		return actions.get(a);
	}

	public Parameter<?> getParameter(SimpleString p) {
		return parameters.get(p);
	}
	
	public Type<?> getType(SimpleString t) {
		return types.get(t);
	}

	public Constant<?> getConstant(SimpleString c) {
		return cFluents.get(c);
	}

	public ConstantFunction<?> getConstantFunction(SimpleString c) {
		return cFluentFunctions.get(c);
	}

	public Fluent<?> getFluent(SimpleString f) {
		return fluents.get(f);
	}
	
	public FluentFunction<?> getFluentFunction(SimpleString f) {
		return fluentFunctions.get(f);
	}

	public Action getAction(SimpleString a) {
		return actions.get(a);
	}
	*/
	
}
